package com.reverie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reverie.common.pojo.CommonPageReq;
import com.reverie.config.CommonException;
import com.reverie.config.util.DateUtils;
import com.reverie.dto.req.CouponQueryParam;
import com.reverie.entity.Coupon;
import com.reverie.entity.Member;
import com.reverie.mapper.CouponMapper;
import com.reverie.service.ICouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reverie.service.IMemberService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Rui.Zhou
 * @since 2024-02-03
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {

    @Resource
    private IMemberService memberService;

    @Override
    public Page<Coupon> queryPage(CommonPageReq<CouponQueryParam> queryPageParam) {
        CouponQueryParam couponQueryParam = queryPageParam.getQueryParam();
        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
        if (couponQueryParam != null) {
            if (StringUtils.hasLength(couponQueryParam.getCouponId())) {
                wrapper.lambda().eq(Coupon::getCouponId, couponQueryParam.getCouponId());
            }
            if (StringUtils.hasLength(couponQueryParam.getName())) {
                wrapper.lambda().like(Coupon::getName, couponQueryParam.getName());
            }
            if (StringUtils.hasLength(couponQueryParam.getSearchKey())) {
                wrapper.lambda().and(item -> item.eq(Coupon::getIsUsed,false));
                wrapper.lambda().and(item -> item.eq(Coupon::getCouponId, couponQueryParam.getSearchKey()));
            }
            if (couponQueryParam.getState() != null) {
                wrapper.lambda().eq(Coupon::getState, couponQueryParam.getState());
            }
            if (couponQueryParam.getUsed() != null) {
                wrapper.lambda().eq(Coupon::getIsUsed, couponQueryParam.getUsed());
            }
            if (StringUtils.hasLength(couponQueryParam.getPhone())) {
                Member member = memberService.queryByPhone(couponQueryParam.getPhone());
                if (member == null) {
                    return new Page<>();
                }
                wrapper.lambda().eq(Coupon::getUserId, member.getUserId());
            }
        }
        wrapper.lambda().orderByDesc(Coupon::getCpId);
        Page<Coupon> couponPage = new Page<>(queryPageParam.getPageNo(), queryPageParam.getPageSize());
        page(couponPage, wrapper);
        buildRecords(couponPage.getRecords());
        return couponPage;
    }

    @Override
    public Boolean bind(Coupon coupon) {
        Member member = memberService.queryByPhone(coupon.getMemberPhone());
        if(member == null){
            throw new CommonException("该手机号还未注册");
        }
        Coupon couponInfo = getById(coupon.getCpId());
        couponInfo.setUserId(member.getUserId());
        couponInfo.setState(true);
        return updateById(couponInfo);
    }

    @Override
    public Boolean cancelOrder(String couponId) {
        Coupon coupon = getByCouponId(couponId);
        if(coupon != null){
            coupon.setIsUsed(false);
            coupon.setLimitTimes(coupon.getLimitTimes() + 1);
        }
        return updateById(coupon);
    }

    @Override
    public Coupon getByCouponId(String couponId) {
        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Coupon::getCouponId,couponId);
        return getOne(wrapper);
    }

    @Override
    public List<Coupon> listByCouponCodes(Set<String> couponIds) {
        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(Coupon::getCouponId,couponIds);
        return list(wrapper);
    }

    private void buildRecords(List<Coupon> records) {
        if (!CollectionUtils.isEmpty(records)) {
            Set<Integer> memberIds = new HashSet<>();
            records.forEach(item -> {
                memberIds.add(item.getUserId());
            });

            Map<Integer, Member> memberMap;
            if (!CollectionUtils.isEmpty(memberIds)) {
                List<Member> members = memberService.listByIds(memberIds);
                memberMap = members.stream().collect(Collectors.toMap(Member::getUserId, m -> m));
            } else {
                memberMap = new HashMap<>();
            }
            records.forEach(item -> {
                String expiresStartTime = DateUtils.formatLongTime((long)item.getExpiresStart() * 1000);
                String expiresEndTime = DateUtils.formatLongTime((long)item.getExpiresEnd() * 1000);
                item.setExpiresStartTime(expiresStartTime);
                item.setExpiresEndTime(expiresEndTime);
                if (item.getUserId() != null) {
                    Member member = memberMap.getOrDefault(item.getUserId(), null);
                    if (member != null) {
                        item.setMemberPhone(member.getUserName());
                    }
                }
            });

        }
    }
}
